﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace MiaProject
{
    class Steering
    {
        private Vector3 wanderTarget;
        private float wanderJitter;
        private float wanderRadius;
        private float wanderDistance;
        //private float wallDetectionFeelerLength; //comprimento das antenas


        //public int steeringType;

        public Steering()
        {
            wanderJitter = 80.0f;
            wanderRadius = 30.0f;
            wanderDistance = 40.0f;

            //wallDetectionFeelerLength = 100;

            //create a vector to a target position on the wander circle
            double theta = -0.5; //valor aleatorio
            wanderTarget = new Vector3((float)(wanderRadius * Math.Cos(theta)), (float)(wanderRadius * Math.Sin(theta)), 0.0f);

        }//end method
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        public Vector3 calculateSteering(Vector3 pos,Vector3 vel,float maxVel, Vector3 targetPos, int steeringType,float timeElapsed)
        {
            //steeringType = type;
            switch(steeringType)
            {
                case 1://SEEK 
                    return seek(pos,vel,maxVel, targetPos);
                    
                /*case FLEE: 
                    return flee(actor, targetPos);
                    break;
		        */
                case 2://ARRIVE 
                    //return arrive(actor, targetPos);
		            //return arrive(pos, targetPos,vel,maxVel);
                    break;
		        
                case 3://WANDER: 
                    //return wander(pos,dir,timeElapsed);//+seek(pos,vel,maxVel, targetPos);
                    break;		

            }
            return seek(pos,vel,maxVel, targetPos);
            //return wander(actor,timeElapsed);
        }//end of method
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        public Vector3 seek(Vector3 pos,Vector3 vel,float maxVel, Vector3 targetPos)
        {
            //Vector3 pos(actor->modelo->getX(),actor->modelo->getY(),actor->modelo->getZ());
            Vector3 toTarget = targetPos - pos;
    
            //calculate the distance to the target
            //double dist = toTarget.lenghtSqr();
            //float deceleration = 1;
    
            //if(dist >1)
            //{
                Vector3 desiredVelocity;
	            desiredVelocity = targetPos - pos;
	            //desiredVelocity.normalize();
	            desiredVelocity *= maxVel;

	            return (desiredVelocity - vel);
            //}
            //actor->next_pos++;
            //return Vector3.Zero;
   
        }//end of method
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Vector3 wander(Vector3 pos,Vector3 dir,float timeElapsed)
        { 
            //this behavior is dependent on the update rate, so this line must
            //be included when using time independent framerate.
            double JitterThisTimeSlice = wanderJitter * timeElapsed * 9;

            Vector3 tmp = new Vector3((float)(randomClamped() * JitterThisTimeSlice), (float)(randomClamped() * JitterThisTimeSlice), 0.0f);
   
            ///printf("\n\n J= %lf", JitterThisTimeSlice);
            //wanderTarget.print();
            //tmp.print();
   
            //first, add a small random vector to the target's position
            wanderTarget += tmp;

            //reproject this new vector back on to a unit circle
            wanderTarget.Normalize();

            //increase the length of the vector to the same as the radius
            //of the wander circle
            wanderTarget *= wanderRadius;
            //wanderTarget.print();

            //Pozzer
            Vector3 target = pos;
            target += (dir*wanderDistance);
            target += wanderTarget;
   
            return target - pos; 
        } 

        private float randomClamped()
        {
            Random rand = new Random();


            float r = (float)(1.0f - (((float)rand.NextDouble() % 1000) / 500.0));
           //printf("\nR= %.2f", r);
           return r;
        }
    }//end class
}
